package com.jianguozh.difs.framework.security.manager;

import cn.hutool.db.Entity;
import com.jianguozh.difs.common.constant.ApiErrorCode;
import com.jianguozh.difs.common.exception.DifsException;
import com.jianguozh.difs.framework.security.AuthenticatedUser;
import com.jianguozh.difs.framework.security.service.DifsUserDetailsDao;
import com.jianguozh.difs.framework.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 认证管理器
 *
 * @author hanrs
 * @email 4076130@qq.com
 * @since 2022/3/14 17:54
 */
@Component
public class AuthManager {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private DifsUserDetailsDao difsUserDetailsDao;

    public String authenticate(String username, String password, String clientId) {

        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,
                    password);
            Authentication authentication = authenticationManager.authenticate(authenticationToken);
            verifyClient(username, clientId);
            AuthenticatedUser authenticatedUser = (AuthenticatedUser) authentication.getPrincipal();
            authenticatedUser.setIssueClientId(clientId);
            return TokenUtils.createToken(authenticatedUser);
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                throw new DifsException(ApiErrorCode.BADCREDENTIALS);
            }
            e.printStackTrace();
            throw new DifsException(e.getMessage());
        }
    }

    private void verifyClient(String username, String clientId) {
        List<Entity> list = difsUserDetailsDao.selecListUserClient(username);
        long count = list.stream().filter(e -> e.getStr("id").equals(clientId)).count();
        if (count < 1) {
            throw new DifsException(ApiErrorCode.CLIENT_UNSUPPORT);
        }
    }

}
